package server

import (
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/enjoy_5/spikes-rpc/internal/model"
	pb "gitee.com/enjoy_5/spikes-rpc/proto/spikes"
	redis1 "gitee.com/xuxinzhi2206/corehub/database/redis"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"log"
	"sync"
	"time"
)

// 创建秒杀活动
func CreateSpikesActivity(in *pb.CreateSpikesActivityRequest) (*model.SpikesActivity, error) {
	s := model.SpikesActivity{
		SpikesTitle:    in.SpikesTitle,
		SpikeStartTime: in.SpikeStartTime,
		SpikeEndTime:   in.SpikeEndTime,
	}
	return s.CreateSpokes()
}

// 获取秒杀活动列表
func GetSpikesActivityList() ([]*pb.SpikesActivity, error) {
	s := model.SpikesActivity{}
	list, err := s.GetSpokesActivityList()
	if err != nil {
		return nil, fmt.Errorf("活动列表查询失败::%v", err)
	}
	var plist []*pb.SpikesActivity
	for _, val := range list {
		plist = append(plist, &pb.SpikesActivity{
			SpikesActivityID: int64(val.ID),
			SpikesTitle:      val.SpikesTitle,
			SpikeStartTime:   val.SpikeStartTime,
			SpikeEndTime:     val.SpikeEndTime,
			SpikeStatus:      val.SpikesStatus,
		})
	}
	return plist, err
}

// 获取秒杀商品列表
func GetSpikesGoodsList(in *pb.GetSpikesGoodsListRequest) (pbSpikesList []*pb.SpikesGoodsList, err error) {
	s := model.SpikesGoodsSku{
		SpikesID: in.SpikesActivityID,
	}
	//判断缓存中是否有值
	key := fmt.Sprintf("spikes:activity_id_%d", in.SpikesActivityID)
	if in.Page > 0 && in.PageSize > 0 {
		key = fmt.Sprintf("%s_page_%d_pageSize_%d", key, in.Page, in.PageSize)
	}
	spikes, _ := redis1.GetRedis(key)
	if spikes.Val() != "" {
		if er := json.Unmarshal([]byte(spikes.Val()), &pbSpikesList); er != nil {
			return nil, fmt.Errorf("解析缓存数据失败：：%v", er)
		}
		return pbSpikesList, nil
	}
	var once sync.Once
	var res []*model.SpikesGoodsSku
	//单列模式
	once.Do(func() {
		res, err = s.GetSpikesGoodsList(in.Page, in.PageSize) //没有就从数据库查
		if err != nil {
			log.Printf("数据库查询失败: %v", err)
			return
		}
	})
	if err != nil || len(res) == 0 {
		return nil, errors.New("查询列表为空")
	}
	for _, v := range res {
		price32 := decimal.NewFromFloat(v.Price).StringFixed(2)
		spikesPrice32 := decimal.NewFromFloat(v.SpikesPrice).StringFixed(2)
		pbSpikesList = append(pbSpikesList, &pb.SpikesGoodsList{
			SpikesActivityID: v.SpikesID,
			GoodsSkuID:       v.SkuID,
			SpikesStock:      v.SpikesStock,
			Price:            price32,
			SpikesPrice:      spikesPrice32,
		})
	}
	m, _ := json.Marshal(pbSpikesList)
	_ = redis1.SetRedis(key, string(m), time.Minute*10)
	return pbSpikesList, nil
}

// 创建 秒杀商品关联
func CreateSpikesGoodsSku(in *pb.CreateSpikesGoodsSkuRequest) (*model.SpikesGoodsSku, error) {
	//判断活动是否存在
	s := model.SpikesActivity{
		Model: gorm.Model{
			ID: uint(in.SpikesActivityID),
		},
	}
	err := s.GetSpokesBySpikesID()
	if err != nil {
		return nil, errors.New("秒杀活动不存在")
	}
	//创建 秒杀商品关联活动
	sg := model.SpikesGoodsSku{
		SpikesID:    in.SpikesActivityID,
		SkuID:       in.GoodsSkuID,
		Price:       float64(in.Price),
		SpikesStock: in.SpikesStock,
		SpikesPrice: float64(in.SpikesPrice),
	}
	return sg.CreateSpikesGoodsSku()
}

// 修改库存
func UpdateGoodsStock(in *pb.UpdateSpikesStockByGoodsIDRequest) error {
	s := model.SpikesGoodsSku{
		SpikesID: in.SpikesActivityID,
	}
	err := s.UpdateSpokesStockBySkuId(in.GoodsID, in.Num)
	if err != nil {
		return errors.New("扣减库存失败")
	}
	return nil
}

// 修改库存回滚
func RoUpdateGoodsStock(in *pb.UpdateSpikesStockByGoodsIDRequest) error {
	s := model.SpikesGoodsSku{
		SpikesID: in.SpikesActivityID,
	}
	err := s.UpdateSpokesStockBySkuId(in.GoodsID, -in.Num)
	if err != nil {
		return errors.New("回滚库存失败")
	}
	return nil
}

func GetSpikesGoodsDetail(in *pb.GetSpikesGoodsDetailRequest) (info *pb.SpikesGoodsDetail, err error) {
	var s model.SpikesGoodsSku
	res, err := s.SpokesStockDetail(in.SkuID, in.SpikesActivityID)
	if err != nil {
		return nil, fmt.Errorf("查询商品详情失败::%v", err)
	}
	spikesPrice := decimal.NewFromFloat(res.SpikesPrice).StringFixed(2)
	info = &pb.SpikesGoodsDetail{
		SpikesID:    res.SpikesID,
		SkuID:       res.SkuID,
		SpikesStock: res.SpikesStock,
		SpikesPrice: spikesPrice,
	}
	return info, nil
}
